#pragma once
#include <list>
#include "Xps/Protocol/IProtocol.h"
#include "Xps/Object/IObjectFactory.h"
#include "ClientSession.h"

namespace Xps
{
    namespace TCP
    {
        class Server :
            public IProtocol
        {
        public:
            Server(const std::string &_Name, const short &_Port, const IObjectFactory *_ObjectFactory);
            ~Server(void);

            virtual const std::string & getName() const;
            virtual void Start();
            virtual void Stop();
            virtual void Send(IPacket::Ptr _Packet);

        private:
            typedef std::list<ClientSession::Ptr >::iterator ClientSessionIterator;

            void Listner();
            void Sender();
            void Sweeper();
            void ProcessPackets();

            void Initialize();

            void SecureIn();

            void SecureOut();

            std::string name;
            bool is_running;
            short port;
            boost::thread th_listner;
            boost::thread th_sender;
            boost::thread th_sweeper;
            boost::thread th_process_packets;
            boost::shared_ptr<asio::io_service> io_service;
            boost::shared_ptr<tcp::acceptor> acceptor;
            std::list<ClientSession::Ptr > connected_clients;
            concurrent_out_queue outgoing_queue;
            concurrent_in_queue incomming_queue;
            CRITICAL_SECTION critical_section;
            HANDLE sender_event;
            HANDLE recieve_event;
            const IObjectFactory *object_factory;
        };
    };

};
